    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpr.tads.suck.model;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;

/**
 *
 * @author julio
 */
public class PessoaDao {

    private final Connection connection;
    private final String sqllist = "select * from pessoa p, endereco e where e.id=p.endereco_id and p.perfil=?";
    private final String sqlsearch = "select * from pessoa p, endereco e where e.id=p.endereco_id and p.perfil=? and (UPPER(p.nome) like UPPER(?) or p.cpf=? or p.crm=? or p.especialidade=?)";
    private final String sqldel = "delete from pessoa where id=?";
    private final String sqlone = "select * from pessoa p, endereco e  where e.id=p.endereco_id and p.id=?";
    private final String sqlinsertall = "insert into pessoa(nome,cpf,endereco_id,tel,email,perfil,senha,crm,especialidade,plano_id,numeroplano,tipoplano,datacad)values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
    private final String sqlinstA = "insert into pessoa(nome,cpf,endereco_id,tel,email,perfil,senha,crm,especialidade)values(?,?,?,?,?,?,?,?,?)";
    private final String sqlendereco = "insert into endereco (logradouro,numero,bairro,cidade,estado) values(?,?,?,?,?)";
    private final String sqlupend = "update endereco set logradouro=?,numero=?,estado=?,bairro=?,cidade=? where id=?";
    private final String sqluppes = "update pessoa set nome=?,tel=?,email=?,cpf=?,crm=?,especialidade=?,plano_id=?,numeroplano=?,tipoplano=? where id=?";

    public PessoaDao() throws IOException, FileNotFoundException, ClassNotFoundException, SQLException {
        this.connection = ConnectionFactory.getConnection();
    }

    public void addPessoa(Pessoa pessoa) throws SQLException, NoSuchAlgorithmException {
        connection.setAutoCommit(false);
        //PreparedStatement stmt = connection.prepareStatement(sqlinstA,PreparedStatement.RETURN_GENERATED_KEYS);
        PreparedStatement stmt = connection.prepareStatement(sqlinsertall, PreparedStatement.RETURN_GENERATED_KEYS);

        stmt.setString(1, pessoa.getNome());
        stmt.setString(2, pessoa.getCpf());
        stmt.setInt(3, this.gravaEndereco(pessoa));
        // stmt.setDouble(4, pessoa.getTel());
        stmt.setString(4, pessoa.getTel());
        stmt.setString(5, pessoa.getEmail());
        stmt.setString(6, pessoa.getPerfil());
        stmt.setString(7, this.toSHA256(pessoa.getSenha()));
        stmt.setInt(8, pessoa.getCrm());
        stmt.setInt(9, pessoa.getEspecialidade());

        // Plano do paciente
        Plano plano = pessoa.getPlano();
        if (plano != null) {
            stmt.setInt(10, plano.getId());
        } else {
            stmt.setNull(10, Types.INTEGER);
        }

        stmt.setString(11, pessoa.getNumeroplano());
        stmt.setString(12, pessoa.getTipoplano());

        // Data de cadastro
        // pessoa.setDatacad(new Date());
        // stmt.setDate(13, pessoa.getDatacad());
        stmt.setDate(13, new java.sql.Date(System.currentTimeMillis()));

        stmt.executeUpdate();
        connection.commit();
        stmt.close();
        throw new AvisoException("Dados Inseridos com sucesso!");
    }

    public void upPessoa(Pessoa pessoa) throws SQLException, NoSuchAlgorithmException {
        connection.setAutoCommit(false);
        PreparedStatement stmt = connection.prepareStatement(sqluppes, PreparedStatement.RETURN_GENERATED_KEYS);
        stmt.setString(1, pessoa.getNome());
        this.upEndereco(pessoa);
        // stmt.setDouble(2, pessoa.getTel());
        stmt.setString(2, pessoa.getTel());
        stmt.setString(3, pessoa.getEmail());
        stmt.setString(4, pessoa.getCpf());
        stmt.setInt(5, pessoa.getCrm());
        stmt.setInt(6, pessoa.getEspecialidade());
        //stmt.setString(7, this.toSHA256(pessoa.getSenha()));

        // Plano do paciente
        Plano plano = pessoa.getPlano();
        if (plano != null) {
            stmt.setInt(7, plano.getId());
        } else {
            stmt.setNull(7, Types.INTEGER);
        }
        stmt.setString(8, pessoa.getNumeroplano());
        stmt.setString(9, pessoa.getTipoplano());

        stmt.setInt(10, pessoa.getId());

        stmt.executeUpdate();
        connection.commit();
        stmt.close();
        throw new AvisoException("Dados Atualizados com sucesso!");
    }

    public List<Pessoa> listPessoa(String perfil) throws SQLException {
        PreparedStatement stmt = connection.prepareStatement(sqllist);
        stmt.setString(1, perfil);
        ResultSet rs = stmt.executeQuery();
        List<Pessoa> listPessoa = new ArrayList();

        while (rs.next()) {
            Pessoa pessoa = ParsePessoaSQL(rs);
            listPessoa.add(pessoa);
        }

        return listPessoa;
    }

    public List<Pessoa> listPessoa(String cpf, String nome, String perfil, int crm, int esp) throws SQLException {

        PreparedStatement stmt = connection.prepareStatement(sqlsearch);
        System.out.println(perfil);
        stmt.setString(1, perfil);
        // stmt.setString(2, nome.toUpperCase());
        stmt.setString(2, "%" + nome + "%");
        stmt.setString(3, cpf.replaceAll("\\D", ""));
        stmt.setInt(4, crm);
        stmt.setInt(5, esp);
        ResultSet rs = stmt.executeQuery();
        List<Pessoa> listPessoa = new ArrayList();

        while (rs.next()) {
            Pessoa pessoa = ParsePessoaSQL(rs);
            listPessoa.add(pessoa);
            System.out.println(pessoa.getNome());
        }
        return listPessoa;
    }

    private Pessoa ParsePessoaSQL(ResultSet rs) throws SQLException {
        Pessoa pessoa = new Pessoa();
        Endereco endereco = new Endereco();
        pessoa.setNome(rs.getString("nome"));
        pessoa.setEmail(rs.getString("email"));
        // pessoa.setTel(rs.getDouble("tel"));
        pessoa.setTel(rs.getString("tel"));
        pessoa.setCpf(rs.getString("cpf"));
        pessoa.setId(rs.getInt("id"));
        pessoa.setCrm(rs.getInt("crm"));
        pessoa.setEspecialidade(rs.getInt("especialidade"));
        endereco.setBairro(rs.getString("bairro"));
        endereco.setCidade(rs.getString("cidade"));
        endereco.setEstado(rs.getString("estado"));
        endereco.setLogradouro(rs.getString("logradouro"));
        endereco.setNumero(rs.getInt("numero"));
        pessoa.setEndereco(endereco);

        int idPlano = rs.getInt("plano_id");
        if (idPlano > 0) {
            try {
                // PlanoDao pd = new PlanoDao();
                // Plano p = pd.listPlano(idPlano);
                // pessoa.setPlano(p);
                pessoa.setPlano(new PlanoDao().listPlano(idPlano));
            } catch (IOException | ClassNotFoundException | SQLException ex) {
                System.out.println(ex.getMessage());
            }
        }
        pessoa.setNumeroplano(rs.getString("numeroplano"));
        pessoa.setTipoplano(rs.getString("tipoplano"));
        pessoa.setDatacad(rs.getDate("datacad"));

        return pessoa;
    }

    public Pessoa listPessoa(double cpf) throws SQLException {
        PreparedStatement stmt = connection.prepareStatement(sqlone);
        stmt.setDouble(1, cpf);
        System.out.println(cpf);
        ResultSet rs = stmt.executeQuery();

        rs.next();
        Pessoa pessoa = ParsePessoaSQL(rs);

        //System.out.println(rs.getString("logradouro"));

        return pessoa;
    }

    public void delPessoa(int id) throws SQLException {
        connection.setAutoCommit(false);
        PreparedStatement stmt = connection.prepareStatement(sqldel);
        int end = listPessoa(id).getId();
        stmt.setInt(1, id);
        stmt.execute();
        delEndereco(end);
        connection.commit();
        stmt.close();
        throw new AvisoException("Atendente Excluido com Sucesso!");
    }

    private void delEndereco(int id) throws SQLException {
        PreparedStatement stmt = connection.prepareStatement("delete from endereco where id=?");
        stmt.setInt(1, id);
        stmt.execute();
        stmt.close();
    }

    private int gravaEndereco(Pessoa pessoa) throws SQLException {
        PreparedStatement stm = connection.prepareStatement(sqlendereco, PreparedStatement.RETURN_GENERATED_KEYS);
        stm.setString(1, pessoa.getEndereco().getLogradouro());
        stm.setInt(2, pessoa.getEndereco().getNumero());
        stm.setString(3, pessoa.getEndereco().getBairro());
        stm.setString(4, pessoa.getEndereco().getCidade());
        stm.setString(5, pessoa.getEndereco().getEstado());

        stm.execute();
        return this.lerId(stm);
    }

    private void upEndereco(Pessoa pessoa) throws SQLException {
        PreparedStatement stm = connection.prepareStatement(sqlupend, PreparedStatement.RETURN_GENERATED_KEYS);
        stm.setString(1, pessoa.getEndereco().getLogradouro());
        stm.setInt(2, pessoa.getEndereco().getNumero());
        stm.setString(3, pessoa.getEndereco().getEstado());
        stm.setString(4, pessoa.getEndereco().getBairro());
        stm.setString(5, pessoa.getEndereco().getCidade());
        stm.setInt(6, pessoa.getId());

        stm.execute();
    }

    private int lerId(PreparedStatement stmt) throws SQLException {
        ResultSet rs = stmt.getGeneratedKeys();
        rs.next();
        return rs.getInt(1);
    }

    private String toSHA256(String password) {
        return DigestUtils.sha256Hex(password);
    }
}
